using UnityEngine;
using System.Collections;
using UnityEditor;
using System;

[CustomEditor(typeof(Ferr2DT_TerrainMaterial))]
public class Ferr2DT_TerrainMaterialEditor : Editor {
	bool topFold    = false;
	bool leftFold   = false;
	bool rightFold  = false;
	bool bottomFold = false;

    int currBody = 0;

	public override void OnInspectorGUI() {
        Undo.SetSnapshotTarget(target, "Modified Terrain Material");
        
		Ferr2DT_TerrainMaterial mat = target as Ferr2DT_TerrainMaterial;
		
		mat.edgeMaterial = (Material)EditorGUILayout.ObjectField("Edge Material", mat.edgeMaterial, typeof(Material), true);
		mat.fillMaterial = (Material)EditorGUILayout.ObjectField("Fill Material", mat.fillMaterial, typeof(Material), true);
		
		topFold = EditorGUILayout.Foldout(topFold,"Top");
		if (topFold) {
			bool showTop = GUILayout.Toggle(mat.Has(Ferr2DT_TerrainDirection.Top), "Use Top");
			mat.Set(Ferr2DT_TerrainDirection.Top, showTop);
			if (showTop) ShowDirection(mat, Ferr2DT_TerrainDirection.Top);
		}
		
		leftFold = EditorGUILayout.Foldout(leftFold,"Left");
		if (leftFold) {
			bool showLeft = GUILayout.Toggle(mat.Has(Ferr2DT_TerrainDirection.Left), "Use Left");
			mat.Set(Ferr2DT_TerrainDirection.Left, showLeft);
			if (showLeft) ShowDirection(mat, Ferr2DT_TerrainDirection.Left);
		}
		
		rightFold = EditorGUILayout.Foldout(rightFold,"Right");
		if (rightFold) {
			bool showRight = GUILayout.Toggle(mat.Has(Ferr2DT_TerrainDirection.Right), "Use Right");
			mat.Set(Ferr2DT_TerrainDirection.Right, showRight);
			if (showRight) ShowDirection(mat, Ferr2DT_TerrainDirection.Right);
		}
		
		bottomFold = EditorGUILayout.Foldout(bottomFold,"Bottom");
		if (bottomFold) {
			bool showBottom = GUILayout.Toggle(mat.Has(Ferr2DT_TerrainDirection.Bottom), "Use Bottom");
			mat.Set(Ferr2DT_TerrainDirection.Bottom, showBottom);
			if (showBottom) ShowDirection(mat, Ferr2DT_TerrainDirection.Bottom);
		}
		
		ShowPreview (mat);

		if (GUI.changed) {
			EditorUtility.SetDirty(target);

            Ferr2DT_PathTerrain[] terrain = GameObject.FindSceneObjectsOfType(typeof(Ferr2DT_PathTerrain)) as Ferr2DT_PathTerrain[];
            for (int i = 0; i < terrain.Length; i++)
            {
                if(terrain[i].TerrainMaterial == mat)
                    terrain[i].RecreatePath();
            }
		}
	}
	
	private void ShowDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir) {
		Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir];
		desc.zOffset   = EditorGUILayout.FloatField( "Z Offset",   desc.zOffset  );
		desc.yOffset   = EditorGUILayout.FloatField( "Y Offset",   desc.yOffset  );
        desc.capOffset = EditorGUILayout.FloatField( "Cap Offset", desc.capOffset);

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Body", GUILayout.Width(40f));
        
        int bodyID = Mathf.Clamp(currBody, 0, desc.body.Length);
        if (GUILayout.Button("<", GUILayout.Width(20f))) currBody = Mathf.Clamp(currBody - 1, 0, desc.body.Length - 1);
        EditorGUILayout.LabelField("" + bodyID, GUILayout.Width(12f));
        if (GUILayout.Button(">", GUILayout.Width(20f))) currBody = Mathf.Clamp(currBody + 1, 0, desc.body.Length - 1);
        bodyID = Mathf.Clamp(currBody, 0, desc.body.Length-1);
        int length = Math.Max(1, EditorGUILayout.IntField(desc.body.Length, GUILayout.Width(32f)));
        EditorGUILayout.LabelField("Total", GUILayout.Width(40f));
        if (length != desc.body.Length) Array.Resize<Rect>(ref desc.body, length);

        EditorGUILayout.EndHorizontal();
        
		desc.body[bodyID]  = AtlasField(aMat, desc.body[bodyID] , aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
        EditorGUILayout.LabelField("Left Cap");
		desc.leftCap  = AtlasField(aMat, desc.leftCap , aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
        EditorGUILayout.LabelField("Right Cap");
		desc.rightCap = AtlasField(aMat, desc.rightCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
	}
	
	private Rect AtlasField(Ferr2DT_TerrainMaterial aMat, Rect aRect, Texture aTexture) {
		
		EditorGUILayout.BeginHorizontal(GUILayout.Height(64), GUILayout.Width(Screen.width-20));
		GUILayout.Space(10);
		GUILayout.Space(64);
		
		Rect  r   = GUILayoutUtility.GetLastRect();
		float max = Mathf.Max (1, Mathf.Max ( aRect.width, aRect.height ));
		r.width   = Mathf.Max (1, (aRect.width  / max) * 64);
		r.height  = Mathf.Max (1, (aRect.height / max) * 64);
		
		GUI      .DrawTexture(new Rect(r.x-1,  r.y-1,    r.width+2, 1),          EditorGUIUtility.whiteTexture);
		GUI      .DrawTexture(new Rect(r.x-1,  r.yMax+1, r.width+2, 1),          EditorGUIUtility.whiteTexture);
		GUI      .DrawTexture(new Rect(r.x-1,  r.y-1,    1,         r.height+2), EditorGUIUtility.whiteTexture);
		GUI      .DrawTexture(new Rect(r.xMax, r.y-1,    1,         r.height+2), EditorGUIUtility.whiteTexture);
		GUI      .DrawTextureWithTexCoords(r, aTexture, aMat.ToUV(aRect));
		GUILayout.Space(10);
		
		Rect result = EditorGUILayout.RectField(aRect);
		EditorGUILayout.EndHorizontal();
		
		return result;
	}
	
	private void ShowPreview(Ferr2DT_TerrainMaterial aMat) {
		if (aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null) return;
		
		GUILayout.Label(aMat.edgeMaterial.mainTexture, GUILayout.Width(Screen.width-25));
		
		Rect texRect = GUILayoutUtility.GetLastRect();
		//texRect.width = aMat.edgeMaterial.mainTexture.width;
        texRect.width = Mathf.Min(Screen.width-25, aMat.edgeMaterial.mainTexture.width);
        texRect.height = (texRect.width / aMat.edgeMaterial.mainTexture.width) * aMat.edgeMaterial.mainTexture.height;
		
		if (topFold   ) ShowPreviewDirection(aMat, Ferr2DT_TerrainDirection.Top,    texRect);
		if (rightFold ) ShowPreviewDirection(aMat, Ferr2DT_TerrainDirection.Right,  texRect);
		if (leftFold  ) ShowPreviewDirection(aMat, Ferr2DT_TerrainDirection.Left,   texRect);
		if (bottomFold) ShowPreviewDirection(aMat, Ferr2DT_TerrainDirection.Bottom, texRect);
	}
	public void ShowPreviewDirection(Ferr2DT_TerrainMaterial aMat, Ferr2DT_TerrainDirection aDir, Rect aBounds) {
		Ferr2DT_SegmentDescription desc = aMat.descriptors[(int)aDir];
        for (int i = 0; i < desc.body.Length; i++)
        {
            DrawRect(aMat.ToScreen( desc.body[i]  ), aBounds);    
        }
		DrawRect(aMat.ToScreen( desc.leftCap  ), aBounds);
		DrawRect(aMat.ToScreen( desc.rightCap ), aBounds);
	}
	private void DrawRect(Rect aRect, Rect aBounds) {
		float x = aBounds.x + aRect.x * aBounds.width;
		float y = aBounds.y + aRect.y * aBounds.height;
		float width  = aRect.width  * aBounds.width;
		float height = aRect.height * aBounds.height;
		
		GUI.DrawTexture(new Rect(x,       y,         width, 1),      EditorGUIUtility.whiteTexture);
		GUI.DrawTexture(new Rect(x,      (y+height), width, 1),      EditorGUIUtility.whiteTexture);
		GUI.DrawTexture(new Rect(x,       y,         1,     height), EditorGUIUtility.whiteTexture);
		GUI.DrawTexture(new Rect(x+width, y,         1,     height), EditorGUIUtility.whiteTexture);
	}
}
